/*
 * SalesData.h
 *
 *  Created on: 2020年11月11日
 *      Author: san
 */

#ifndef SALESDATA_H_
#define SALESDATA_H_
#include <string>
#include <iostream>
#include <tuple>
#include <vector>
#include <algorithm>

#include "Screen.h"
#include "MyException.h"

using std::string;
using std::istream;
using std::ostream;

//template <class T> class std::hash;
class Sales_data
{
public:
	friend class std::hash<Sales_data>;
	// 特例化hash<Sales_data>


	// 友元函数不受类作用域限制
	friend istream &read(istream &is, Sales_data &item);
	friend ostream &print(ostream &os, const Sales_data &item);

	// 构造函数和析构函数
	Sales_data(string, unsigned, double);
	Sales_data(): Sales_data("", 0, 0) { std::cout << "我是第一层委托！1" << std::endl;};
	explicit Sales_data(const string &s): Sales_data(s, 0, 0){};  // 抑制隐式类型转换
	Sales_data(istream &is): Sales_data() {std::cout << "我是第二层委托!2" << std::endl;read(is, *this);};
	Sales_data(const Sales_data &sd): bookNo(sd.bookNo), units_sold(sd.units_sold), revenue(sd.revenue) {}
	~Sales_data();

	// 运算符重载
	friend Sales_data &operator+(const Sales_data &, const Sales_data &);
	Sales_data &operator+=(const Sales_data &);
	friend ostream &operator<<(ostream &os, const Sales_data &);
	friend istream &operator>>(istream &is, Sales_data &);
	friend bool operator ==(const Sales_data &, const Sales_data &);
	friend bool operator !=(const Sales_data &, const Sales_data &);
	operator string() const { return toString();}
	operator double() const { return revenue;}

	// 工具
	std::string isbn() const { return bookNo;}
	int getUnitSold() const { return units_sold; }
	double getRevenue() const { return  revenue; }
	void setbn(string &s) { bookNo = s;}
	void setUnitSold(int &n) {units_sold = n;};
	void setRevenue(double &price) { revenue = price * units_sold;}

	Sales_data &combine(const Sales_data&);  // 抑制隐式类型转换
	double avg_price() const;
	string toString() const;
	Sales_data add(const Sales_data&, const Sales_data&);

private:
	std::string bookNo;
	unsigned units_sold = 0;
	double revenue = 0.0;
};

typedef std::tuple< std::vector<Sales_data>::size_type,
			std::vector<Sales_data>::const_iterator,
			std::vector<Sales_data>::const_iterator > matches;

//bool compareIsbn_v1(const Sales_data &lhs, const Sales_data &rhs)
//{
//	return lhs.isbn() < rhs.isbn();
//}

std::vector<matches> findBook(const std::vector<std::vector<Sales_data>> &files, const string &book);
#endif /* SALESDATA_H_ */
